package com.ruoyi.dev.minio.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.dev.minio.config.MinioConfig;
import com.ruoyi.dev.minio.domain.MinioFile;
import com.ruoyi.dev.minio.dto.MinioResponseDTO;
import com.ruoyi.dev.minio.service.FileHadleService;
import com.ruoyi.dev.minio.service.MinioFileService;
import com.ruoyi.dev.minio.util.MinioClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.Instant;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author sxy
 * @date 2024/03/29
 **/
@Slf4j
@Service
public class FileHadleServiceImpl implements FileHadleService {

    @Autowired
    private MinioClientUtils minioClientUtils;

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    public MinioFileService minioFileService;

    public void fileToMultipartFile(File realFile) {
        //将File转换为MultipartFile
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.APPLICATION_OCTET_STREAM_VALUE
                , true
                , realFile.getName());
        try (InputStream input = new FileInputStream(realFile);
             OutputStream os2 = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os2);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }
        CommonsMultipartFile file = new CommonsMultipartFile(item);
        // 上传至minio
//        boolean flag = uploadFile2(commonsMultipartFile);

        List<MinioResponseDTO> minioResponseDTOList = new ArrayList<>();

        String originalFilename = file.getOriginalFilename();

        String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        log.info("文件拓展名:" + extName);
        //生成新的文件名，存入到minio
        long millSeconds = Instant.now().toEpochMilli();
        String minioFileName = LocalDate.now().getYear() + "-" + LocalDate.now().getMonthValue() + "-" + LocalDate.now().getDayOfMonth()
                + "/" + millSeconds + RandomStringUtils.randomNumeric(3) + "." + extName;

        String contentType = file.getContentType();
        log.info("文件mime:{}", contentType);
        //返回文件大小,单位字节
        long size = file.getSize();
        log.info("文件大小：" + size);

        try {
            String bucketName = minioConfig.getBucketName();
            log.info("开始上传到minio ");
            minioClientUtils.putObject(bucketName, file, minioFileName);
            String fileUrl = minioClientUtils.getObjectUrl(bucketName, minioFileName);
            log.info("完成上传到minio ");

            MinioFile minioFile = new MinioFile();
            minioFile.setOriginalFileName(originalFilename);
            minioFile.setFileExtName(extName);
            minioFile.setFileName(minioFileName);
            minioFile.setFileSize(size);
            minioFile.setMime(contentType);
            minioFile.setIsDelete(NumberUtils.INTEGER_ONE);
            minioFile.setFileUrl(fileUrl);

            boolean insert = minioFileService.insert(minioFile);

            if (insert) {
                MinioResponseDTO minioResponseDTO = new MinioResponseDTO();
                minioResponseDTO.setFileId(minioFile.getId());
                minioResponseDTO.setOriginalFileName(originalFilename);
                minioResponseDTO.setFileUrl(fileUrl);
                minioResponseDTOList.add(minioResponseDTO);
            }
            if(insert){
                realFile.delete();
                System.gc(); // 回收资源
            }
        } catch (Exception e) {
            log.error("上传文件出错:{}", e);
        }

    }


    public void onCallback(File realFile) {
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(() -> {
            try {
                // 这边执行具体的方法
                this.fileToMultipartFile(realFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        executor.shutdown();
    }


}
